"""
NumPy简单入门教程
"""
import numpy as np
import matplotlib.pyplot as plt


# 创建数组
def create_array():
    # 1维数组
    a = np.array([0, 1, 2, 3, 4])
    b = np.array((0, 1, 2, 3, 4))
    c = np.arange(5)
    d = np.linspace(0, 2*np.pi, 10)  # start, end ,number
    print(a)
    print(b)
    print(c)
    print(d)

    # 多维数组
    a = np.array([[11, 12, 13, 14, 15],
                  [16, 17, 18, 19, 20],
                  [21, 22, 23, 24, 25],
                  [26, 27, 28, 29, 30],
                  [31, 32, 33, 34, 35]])
    print(a[2, 3])
    # 数组切片
    print(a[0, 1:4])
    print(a[1:3, 1])
    print(a[:, 3])
    print(a[2:, 2:])
    print(a[::2, ::1])

    # 数组信息
    print(type(a))          # 数组类型  <class 'numpy.ndarray'>
    print(a.dtype)          # 数组元素类型    int32
    print(a.size)           # 数组元素个数    25
    print(a.shape)          # 数组的结构     (5, 5)
    print(a.itemsize)       # 数组元素占用字节数 4
    print(a.ndim)           # 数组的维数     2
    print(a.nbytes)         # 数组元素总计字节数 100


# 操作数组
def operate_array():
    # 创建一维数组
    a = np.arange(25)
    print(a)
    # 将一维数组转为二维数组
    a = a.reshape((5, 5))
    print(a)
    b = np.array([10, 62, 1, 14, 2, 56, 79, 2, 1, 45,
                  4, 92, 5, 55, 63, 43, 35, 6, 53, 24,
                  56, 3, 56, 44, 78])
    print(b)
    b = b.reshape((5, 5))
    print(b)
    # 数组运算
    print(a + b)
    print(a - b)
    print(a * b)
    print(a / b)
    print(a ** 2)
    print(a < b)
    print(a > b)
    print(a.dot(b))

    x = np.array([[1, 2], [3, 4]])
    y = np.array([[5, 6], [7, 8]])
    print(x)
    print(y)
    print(x.dot(y))

    # 数组方法`
    """
    1. sum()、min()和max()函数的作用非常明显。将所有元素相加，找出最小和最大元素
    2. cumsum() 函数将像sum()这样的每个元素相加，但是它首先将第一个元素和第二个元素相加，
    并将计算结果存储在一个列表中，然后将该结果添加到第三个元素中，
    然后再将该结果存储在一个列表中。这将对数组中的所有元素执行此操作，并返回作为列表的数组之和的运行总数
    """
    a = np.arange(10)
    print(a)
    print(a.sum())
    print(a.min())
    print(a.max())
    print(a.cumsum())

    # 索引进阶
    # 花式索引
    """
    使用我们想要检索的特定索引序列对数组进行索引。这反过来返回我们索引的元素的列表
    """
    a = np.arange(0, 100, 10)   # start, end, step
    print(a)
    indices = [1, 5, -2]        # 索引列表
    b = a[indices]
    print(b)

    # 布尔屏蔽
    """
    你所要做的就是将数组传递给涉及数组的条件，它将为你提供一个值的数组，为该条件返回true。
    """
    a = np.linspace(0, 2 * np.pi, 50)   # start, end, num
    b = np.sin(a)
    plt.plot(a, b)
    mask = b > 0
    print(mask)
    plt.plot(a[mask], b[mask], 'bo')
    mask = (b > 0) & (a <= np.pi / 2)
    plt.plot(a[mask], b[mask], 'go')
    # plt.show()        # 绘制图形时去除注释

    # 缺省索引
    """
    不完全索引是从多维数组的第一个维度获取索引或切片的一种方便方法。
    """
    a = np.arange(0, 100, 10)
    b = a[:5]
    c = a[a > 50]
    print(b)
    print(c)
    x = np.array([3, 5, 1, 17, 25, 19, 7, 13, 22, 6])
    y = x[x > 10]           # 元素值大于10的元素数组
    print(x)
    print(y)

    # Where函数
    """
    where() 函数是另外一个根据条件返回数组中的值的有效方法。只需要把条件传递给它，它就会返回一个使得条件为真的元素的列表。
    """
    a = np.arange(0, 100, 10)
    b = np.where(a < 50)
    c = np.where(a >= 50)[0]
    print(b)        # (array([0, 1, 2, 3, 4], dtype=int64),)
    print(c)        # [5 6 7 8 9]


# 程序入口
if __name__ == "__main__":
    # create_array()
    operate_array()
    pass